package com.azxc.rapid.resource.endpoint;

import com.azxc.rapid.core.oss.model.OssFile;
import com.azxc.rapid.core.oss.model.RapidFile;
import com.azxc.rapid.core.secure.annotation.PreAuth;
import com.azxc.rapid.core.tenant.annotation.NonDS;
import com.azxc.rapid.core.tool.api.R;
import com.azxc.rapid.core.tool.constant.RoleConstant;
import com.azxc.rapid.core.tool.utils.FileUtil;
import com.azxc.rapid.core.tool.utils.Func;
import com.azxc.rapid.resource.builder.oss.OssBuilder;
import com.azxc.rapid.resource.entity.Attach;
import com.azxc.rapid.resource.service.IAttachService;
import io.swagger.annotations.Api;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import java.util.HashSet;
import java.util.Set;

/**
 * 对象存储端点
 */
@NonDS
@RestController
@RequestMapping("/oss/endpoint")
@Api(value = "对象存储端点", tags = "对象存储端点")
public class OssEndpoint {
	@Value(value = "${oss.replaceFlag}")
	private Boolean replaceFlag;
	@Value(value = "${oss.oldIP}")
	private String oldIP;
	@Value(value = "${oss.showIP}")
	private String showIP;
	private final Set<String> extNameMap = new HashSet<>();

	{
		extNameMap.add("jpg");
		extNameMap.add("png");
		extNameMap.add("docx");
		extNameMap.add("doc");
		extNameMap.add("xls");
		extNameMap.add("xlsx");
		extNameMap.add("pdf");
		extNameMap.add("avi");
		extNameMap.add("mov");
		extNameMap.add("rmvb");
		extNameMap.add("rm");
		extNameMap.add("flv");
		extNameMap.add("mp4");
		extNameMap.add("mp3");
		extNameMap.add("wmv");
		extNameMap.add("apk");
		extNameMap.add("webm");
		extNameMap.add("rar");
		extNameMap.add("zip");
	}

	/**
	 * 对象存储构建类
	 */
	@Autowired
	private OssBuilder ossBuilder;

	/**
	 * 附件表服务
	 */
	@Autowired
	private IAttachService attachService;

	/**
	 * 创建存储桶
	 *
	 * @param bucketName 存储桶名称
	 * @return Bucket
	 */
	@SneakyThrows
	@PostMapping("/make-bucket")
	@PreAuth(RoleConstant.HAS_ROLE_ADMIN)
	public R makeBucket(@RequestParam String bucketName) {
		ossBuilder.template().makeBucket(bucketName);
		return R.success("创建成功");
	}

	/**
	 * 创建存储桶
	 *
	 * @param bucketName 存储桶名称
	 * @return R
	 */
	@SneakyThrows
	@PostMapping("/remove-bucket")
	@PreAuth(RoleConstant.HAS_ROLE_ADMIN)
	public R removeBucket(@RequestParam String bucketName) {
		ossBuilder.template().removeBucket(bucketName);
		return R.success("删除成功");
	}

	/**
	 * 拷贝文件
	 *
	 * @param fileName       存储桶对象名称
	 * @param destBucketName 目标存储桶名称
	 * @param destFileName   目标存储桶对象名称
	 * @return R
	 */
	@SneakyThrows
	@PostMapping("/copy-file")
	public R copyFile(@RequestParam String fileName, @RequestParam String destBucketName, String destFileName) {
		ossBuilder.template().copyFile(fileName, destBucketName, destFileName);
		return R.success("操作成功");
	}

	/**
	 * 获取文件信息
	 *
	 * @param fileName 存储桶对象名称
	 * @return InputStream
	 */
	@SneakyThrows
	@GetMapping("/stat-file")
	public R<OssFile> statFile(@RequestParam String fileName) {
		return R.data(ossBuilder.template().statFile(fileName));
	}

	/**
	 * 获取文件相对路径
	 *
	 * @param fileName 存储桶对象名称
	 * @return String
	 */
	@SneakyThrows
	@GetMapping("/file-path")
	public R<String> filePath(@RequestParam String fileName) {
		return R.data(ossBuilder.template().filePath(fileName));
	}


	/**
	 * 获取文件外链
	 *
	 * @param fileName 存储桶对象名称
	 * @return String
	 */
	@SneakyThrows
	@GetMapping("/file-link")
	public R<String> fileLink(@RequestParam String fileName) {
		return R.data(ossBuilder.template().fileLink(fileName));
	}

	/**
	 * 上传文件
	 *
	 * @param file 文件
	 * @return ObjectStat
	 */
	@SneakyThrows
	@PostMapping("/put-file")
	public R<RapidFile> putFile(@RequestParam MultipartFile file) {
		if (!extNameMap.contains(FileUtil.getFileExtension(file.getOriginalFilename()))) {
			return R.fail("不允许上传格式为【" + FileUtil.getFileExtension(file.getOriginalFilename()) + "】的文件");
		}
		RapidFile rapidFile = ossBuilder.template().putFile(file.getOriginalFilename(), file.getInputStream());
		Long attachId = buildAttach(file.getName(), file.getSize(), rapidFile);
		rapidFile.setAttachId(attachId);
		return R.data(rapidFile);
	}

	/**
	 * 上传文件
	 *
	 * @param fileName 存储桶对象名称
	 * @param file     文件
	 * @return ObjectStat
	 */
	@SneakyThrows
	@PostMapping("/put-file-by-name")
	public R<RapidFile> putFile(@RequestParam String fileName, @RequestParam MultipartFile file) {
		if (!extNameMap.contains(FileUtil.getFileExtension(file.getOriginalFilename()))) {
			return R.fail("不允许上传格式为【" + FileUtil.getFileExtension(file.getOriginalFilename()) + "】的文件");
		}
		RapidFile rapidFile = ossBuilder.template().putFile(fileName, file.getInputStream());
		Long attachId = buildAttach(fileName, file.getSize(), rapidFile);
		rapidFile.setAttachId(attachId);
		return R.data(rapidFile);
	}

	/**
	 * 上传文件并保存至附件表
	 *
	 * @param file 文件
	 * @return ObjectStat
	 */
	@SneakyThrows
	@PostMapping("/put-file-attach")
	public R<RapidFile> putFileAttach(@RequestParam MultipartFile file) {
		String fileName = file.getOriginalFilename();
		if (!extNameMap.contains(FileUtil.getFileExtension(fileName))) {
			return R.fail("不允许上传格式为【" + FileUtil.getFileExtension(fileName) + "】的文件");
		}
		RapidFile rapidFile = ossBuilder.template().putFile(fileName, file.getInputStream());
		Long attachId = buildAttach(fileName, file.getSize(), rapidFile);
		rapidFile.setAttachId(attachId);
		return R.data(rapidFile);
	}

	/**
	 * 上传文件并保存至附件表
	 *
	 * @param fileName 存储桶对象名称
	 * @param file     文件
	 * @return ObjectStat
	 */
	@SneakyThrows
	@PostMapping("/put-file-attach-by-name")
	public R<RapidFile> putFileAttach(@RequestParam String fileName, @RequestParam MultipartFile file) {
		if (!extNameMap.contains(FileUtil.getFileExtension(file.getOriginalFilename()))) {
			return R.fail("不允许上传格式为【" + FileUtil.getFileExtension(file.getOriginalFilename()) + "】的文件");
		}
		RapidFile rapidFile = ossBuilder.template().putFile(fileName, file.getInputStream());
		Long attachId = buildAttach(fileName, file.getSize(), rapidFile);
		rapidFile.setAttachId(attachId);
		return R.data(rapidFile);
	}

	/**
	 * 构建附件表
	 *
	 * @param fileName  文件名
	 * @param fileSize  文件大小
	 * @param rapidFile 对象存储文件
	 * @return attachId
	 */
	private Long buildAttach(String fileName, Long fileSize, RapidFile rapidFile) {
		String fileExtension = FileUtil.getFileExtension(fileName);
		Attach attach = new Attach();
		if(replaceFlag){
			rapidFile.setLink(rapidFile.getLink().replace(oldIP,showIP));
			rapidFile.setDomain(rapidFile.getDomain().replace(oldIP,showIP));
		}
		attach.setLink(rapidFile.getLink());
		attach.setDomain(rapidFile.getDomain());
		attach.setName(rapidFile.getName());
		attach.setOriginalName(rapidFile.getOriginalName());
		attach.setAttachSize(fileSize);
		attach.setExtension(fileExtension);
		attachService.save(attach);
		return attach.getId();
	}

	/**
	 * 删除文件
	 *
	 * @param fileName 存储桶对象名称
	 * @return R
	 */
	@SneakyThrows
	@PostMapping("/remove-file")
	@PreAuth(RoleConstant.HAS_ROLE_ADMIN)
	public R removeFile(@RequestParam String fileName) {
		ossBuilder.template().removeFile(fileName);
		return R.success("操作成功");
	}

	/**
	 * 批量删除文件
	 *
	 * @param fileNames 存储桶对象名称集合
	 * @return R
	 */
	@SneakyThrows
	@PostMapping("/remove-files")
	@PreAuth(RoleConstant.HAS_ROLE_ADMIN)
	public R removeFiles(@RequestParam String fileNames) {
		ossBuilder.template().removeFiles(Func.toStrList(fileNames));
		return R.success("操作成功");
	}


}
